package cn.tedu.micro.demo.emqx.callback;

import cn.tedu.micro.demo.emqx.context.MqttContext;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.mapper.Mapper;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AllArgsConstructor
@NoArgsConstructor
public class MyMqttCallback implements MqttCallbackExtended {
    private MqttClient mqttClient;
    private MqttContext mqttContext;

    /**
     *调用时机: 当前回调对象所属的连接mqttClient成功连接完毕的时候
     *reconnec: 表示本次连接成功是重连,还是第一次连 false第一次 true重连
     *serverURI: 连接目标地址 address相同
     *当放大调用 代表连接建立成功,可以实现初始化,订阅的操作
     */
    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
        if (reconnect){
            log.info("重新连接,emqx地址:{}",serverURI);
        }else{
            log.info("第一次连接,emqx地址:{}",serverURI);
        }
        //当前回调对象 所属的mqttClient监听订阅主题
        try{
            //普通订阅 群发
            //mqttClient.subscribe("topic01");
            //mqttClient.subscribe("topic02");
            //共享订阅 争抢
            mqttClient.subscribe("$share/test/topic01");
            mqttClient.subscribe("$share/test/topic02");
        }catch (Exception e){
            log.error("订阅主题失败",e);
        }
    }

    /**
     *时间节点: 当前回调对象所属的mqttClient断开连接的时候调用
     *cause: 断开连接的原因,超时,拒绝
     */
    @Override
    public void connectionLost(Throwable cause) {
        log.info("断开连接,原因:{}",cause.getMessage());
    }

    /**
     *调用时机: 当前所属的连接 投递发送消息成功会调用
     *token: 投递消息的完整镜像,可以通过token获取投递消息的所有内容
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        log.info("消息投递成功");
    }

    /**
     *回调时机: 当前所属连接 监听订阅的主题出现新的消息时,会获取消息,调用messageArrived
     *topic: 消息主题来源名字
     *message:消息对象包含消息头消息体消息属性
     *消费功能 可以在messageArrived中完成
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        log.info("从:{}主题,拿到消息:{}",topic,new String(message.getPayload()));
        //来的每条消息,都写入message 覆盖数据 调用redis的客户端执行set命令
        String key="message";
        mqttContext.getRedisTemplate().opsForValue().set(key,new String(message.getPayload()));
    }
}
